﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using OpenCvSharp;
using ExpreRec.Logic.FaceDetection;
using ExpreRec.Logic.Preprocessing;
using ExpreRec.Logic.Expression;
using ExpreRec.Logic.Util;
using ExpreRec.Logic.Model;

namespace ExpreRec.UI
{
    public partial class LocalPictureRecognitionResultForm : Form
    {
        private IplImage image;
        private IplImage faceImage;

        private static HaarFaceDetector detector = new HaarFaceDetector();
        private static GaborExtract extractor = new GaborExtract();
        private static Classification classifier = new Classification();

        private double[] features = null;

        public void SetImage(IplImage image)
        {
            this.image = image;

            reloadPicture();
        }

        private void reloadPicture()
        {
            this.pictureBoxOriginal.Image = image.ToBitmap();
            this.pictureBoxOriginal.Refresh();
            this.pictureBoxFace.Image = null;
            this.buttonGabor.Enabled = false;
            this.buttonExpressionRecognition.Enabled = false;

            this.pictureBoxGabor1.Image = null;
            this.pictureBoxGabor2.Image = null;
            this.pictureBoxGabor3.Image = null;
            this.pictureBoxGabor4.Image = null;
            this.pictureBoxGabor5.Image = null;
        }

        public LocalPictureRecognitionResultForm()
        {
            InitializeComponent();
        }

        private void LocalPictureRecognitionResultForm_Load(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Maximized;
        }

        private void buttonLeftRotate_Click(object sender, EventArgs e)
        {
            image = Processor.RotateLeft(image);
            reloadPicture();
        }

        private void buttonRightRotate_Click(object sender, EventArgs e)
        {
            image = Processor.RotateRight(image);
            reloadPicture();
        }

        private void buttonFaceRecognition_Click(object sender, EventArgs e)
        {
            IList<IplImage> res = detector.Detect(image);

            if (res != null && res.Count != 0)
            {
                CvSize dstSize = new CvSize(Const.GaborMaskSize, Const.GaborMaskSize);
                faceImage = Processor.ReSize(res[0], dstSize, Interpolation.Linear);

                this.pictureBoxFace.Image = faceImage.ToBitmap();
                this.pictureBoxFace.Refresh();

                this.buttonGabor.Enabled = true;
            }
            else
            {
                MessageBox.Show("给定的图片中没有探测到人脸！");
            }
        }

        private void GaborExtract_Click(object sender, EventArgs e)
        {
            //Directory.CreateDirectory("gabor");
            //extractor.gaborFilter("gabor");
        }

        private void buttonGabor_Click(object sender, EventArgs e)
        {
            IplImage[] filteredImages;
            features = extractor.ExtractFeatures(faceImage, out filteredImages);

            this.pictureBoxGabor1.Image = filteredImages[0].ToBitmap();
            this.pictureBoxGabor1.Refresh();
            this.pictureBoxGabor2.Image = filteredImages[1].ToBitmap();
            this.pictureBoxGabor2.Refresh();
            this.pictureBoxGabor3.Image = filteredImages[2].ToBitmap();
            this.pictureBoxGabor3.Refresh();
            this.pictureBoxGabor4.Image = filteredImages[3].ToBitmap();
            this.pictureBoxGabor4.Refresh();
            this.pictureBoxGabor5.Image = filteredImages[4].ToBitmap();
            this.pictureBoxGabor5.Refresh();

            this.buttonExpressionRecognition.Enabled = true;
        }

        private void buttonExpressionRecognition_Click(object sender, EventArgs e)
        {
            KeyValuePair<IList<string>, IList<GaborItem>> res = classifier.GaborKNNLoadModel();
            if (res.Key.Count == 0 || res.Value.Count == 0)
            {
                MessageBox.Show("图片库不存在，请重新进行预处理！");
            }
            else
            {
                if (Variable.KNNParamSet)
                {
                    IList<KNNItem> result = classifier.GaborKNNClassification(res.Key, res.Value, features, Variable.KNNParamDistVoteFlag, Variable.KNNParamDistR, Variable.KNNParamK);

                    listViewResult.Items.Clear();

                    double total = 0;

                    foreach (KNNItem item in result)
                    {
                        total += item.V;
                    }

                    double firstRate = -1;

                    foreach (KNNItem item in result)
                    {
                        double rate = item.V * 100 / total;

                        if (firstRate == -1)
                            firstRate = rate;

                        ListViewItem listViewItem = new ListViewItem(item.Label);
                        listViewItem.SubItems.Add(rate.ToString() + "%");

                        listViewResult.Items.Add(listViewItem);
                    }

                    MessageBox.Show(string.Format("系统判断最后可能的表情为{0}，可能性是{1}", result[0].Label, firstRate));
                }
                else
                {
                    MessageBox.Show("KNN参数尚未设置，请先进行训练！");
                }
            }
        }
    }
}
